package com.delay.queue.delayedqueue.rediskeyexpire;

/**
 * @author gxing
 * @desc Redis 键过期监听器实现延时队列,加分布式锁解决多实例重复监听问题
 * @date 2021/3/11
 */
//@Component
//public class RedisKeyExpireListenerWithLock extends KeyExpirationEventMessageListener {

//    @Autowired
//    private RedisTemplate<String, Object> redisTemplate;

//    private static final Topic KEYEVENT_EXPIRED_TOPIC = new PatternTopic("__keyevent@*__:expired");

    // 自定义监听通道,指定db
//    private static final Topic KEYEVENT_EXPIRED_TOPIC = new PatternTopic("__keyevent@4__:expired");

    /**
     * 添加键过期监听器,注入监听容器
     *
     * @param listenerContainer
     */
/*    public RedisKeyExpireListenerWithLock(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }*/


    /**
     * 重写父类方法,将监听器与通道绑定并注册到监听容器
     *
     * @param listenerContainer
     */
/*    @Override
    public void doRegister(RedisMessageListenerContainer listenerContainer) {
        listenerContainer.addMessageListener(this, KEYEVENT_EXPIRED_TOPIC);
    }*/

    /**
     * 处理监听到的消息,业务处理
     */
/*    @Override
    public void doHandleMessage(Message message) {
        String key = message.toString();
        // 注意：Redis 键空间通知是针对库的所有键
        // 在设置元素时可以给键设置前缀以标识所属业务
        if (!key.startsWith("DelayOrder")) {
            return;
        }

        String lockKey = "lock_" + key;
        Boolean lock = lock(lockKey);
        System.out.println(lock);
        if (!lock) {
            return;
        }

        System.out.println("延时任务 Key:" + message.toString());
        // 拿到 key 再到 Redis 获取任务并处理
        // 处理成功, 删除任务
        // 处理失败, 重新将 key 加入到过期队列中待下次处理
        try {

            // 释放锁,这里睡5秒后解锁,防止程序太快,导致1服务释放锁后,2服务才开始获取锁
            Thread.sleep(5000);
            unlock(lockKey);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }*/

    /**
     * 加锁
     *
     * @param lockKey
     * @return
     */
/*    private Boolean lock(String lockKey) {
        return redisTemplate.opsForValue().setIfAbsent(lockKey, "lock", 10, TimeUnit.SECONDS);
    }*/

    /**
     * 解锁
     *
     * @param lockKey
     */
/*    private void unlock(String lockKey) {
        redisTemplate.delete(lockKey);
    }*/
//}
